﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace MinhUtils
{
    public static class FileUtil
    {
        public enum SaveMode
        {
            Overwrite
        }

        /// <summary>
        /// Copy a directory and its contents
        /// </summary>
        public static int CopyDirectory(string strSrcPath, string strDestPath)
        {
            System.IO.DirectoryInfo diSrc = new System.IO.DirectoryInfo(strSrcPath);
            System.IO.DirectoryInfo diDest = new System.IO.DirectoryInfo(strDestPath);
            return CopyDirectory(diSrc, diDest);
        }

        /// <summary>
        /// Copy a directory and its contents
        /// </summary>
        public static int CopyDirectory(System.IO.DirectoryInfo source, System.IO.DirectoryInfo target)
        {
            try
            {
                // Check if the source directory exists, if not, return.
                if (System.IO.Directory.Exists(source.FullName) == false)
                {
                    return -1;
                }

                // Check if the target directory exists, if not, create it.
                if (System.IO.Directory.Exists(target.FullName) == false)
                {
                    System.IO.Directory.CreateDirectory(target.FullName);
                }

                // Copy each file into it's new directory.
                foreach (System.IO.FileInfo fi in source.GetFiles())
                {
                    fi.CopyTo(System.IO.Path.Combine(target.ToString(), fi.Name), true);
                }

                // Copy each subdirectory using recursion.
                foreach (System.IO.DirectoryInfo diSourceSubDir in source.GetDirectories())
                {
                    System.IO.DirectoryInfo nextTargetSubDir = target.CreateSubdirectory(diSourceSubDir.Name);
                    CopyDirectory(diSourceSubDir, nextTargetSubDir);
                }

                return 1;
            }
            catch
            {
                return -1;
            }
        }

        /// <summary>
        /// Create all folders and subfolders as specified by path if not exist
        /// </summary>
        /// <param name="folderPath"></param>
        public static void CreateFolder(string folderPath)
        {
            if (System.IO.Directory.Exists(folderPath))
                return;

            System.IO.Directory.CreateDirectory(folderPath);
        }

        /// <summary>
        /// Replace invalid characters from a file or folder name with spaces (" ")
        /// </summary>
        /// <param name="folderPath">File or folder name</param>
        /// <returns></returns>
        public static string EliminateInvalidCharacters(string name)
        {
            StringBuilder sb = new StringBuilder(name);
            sb.Replace(@"\", " ");
            sb.Replace(@"/", " ");
            sb.Replace(@":", " ");
            sb.Replace(@"?", " ");
            sb.Replace("\"", " ");
            sb.Replace(@"<", " ");
            sb.Replace(@">", " ");
            sb.Replace(@"|", " ");
            sb.Replace(@"*", " ");

            return sb.ToString();
        }

        public static void DeleteFolder(string folderPath)
        {
            //http://www.devasp.net/net/articles/display/623.html
            System.IO.DirectoryInfo diSource = new System.IO.DirectoryInfo(folderPath);

            foreach (System.IO.FileInfo fi in diSource.GetFiles())
                fi.Delete();

            diSource.Delete();
        }

        public static string GetDesktopPath()
        {
            //http://www.thescarms.com/dotnet/SpecialFolders.aspx
            return System.Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
        }

        /// <summary>
        /// Return path to Windows temp directory
        /// </summary>
        public static string GetTempPath()
        {
            //http://bytes.com/topic/c-sharp/answers/255098-how-get-windows-temp-directory
            return System.IO.Path.GetTempPath();
        }

        /// <summary>
        /// Return a random filename with the same extension
        /// </summary>
        public static string GetRandomFileName(string fileName)
        {
            return (DateTime.Now.Ticks.ToString() + GetFileExtension(fileName));
        }

        /// <summary>
        /// Returns true if the given file path is a folder.
        /// </summary>
        /// <param name="Path">File path</param>
        /// <returns>True if a folder</returns>
        public static bool IsFolder(string path)
        {
            //http://www.jonasjohn.de/snippets/csharp/is-folder.htm
            return ((System.IO.File.GetAttributes(path) & System.IO.FileAttributes.Directory) == System.IO.FileAttributes.Directory);
        }

        /// <summary>
        /// Get filename from a Uri
        /// </summary>
        public static string GetFileName(string uri)
        {
            if (uri.ToLower().StartsWith("http"))
            {
                int i = uri.LastIndexOf("/");

                if (i == -1 && i == uri.Length)
                    return String.Empty;
                else
                    return uri.Remove(0, i + 1);
            }
            else
            {
                System.IO.FileInfo fileInfo = new System.IO.FileInfo(uri);
                return fileInfo.Name;
            }
        }

        /// <summary>
        /// Get file extension from a Uri
        /// </summary>
        public static string GetFileExtension(string uri)
        {
            if (uri.ToLower().StartsWith("http"))
            {
                int i = uri.LastIndexOf(".");

                if (i < 0 || i == uri.Length - 1 || i < uri.LastIndexOf('/'))
                    return String.Empty;
                else
                    return uri.Remove(0, i);
            }
            else
            {
                System.IO.FileInfo fileInfo = new System.IO.FileInfo(uri);
                return fileInfo.Extension;
            }
        }

        public static HashSet<string> ReadFile(string filePath)
        {
            HashSet<string> hashSet = new HashSet<string>();

            try
            {
                if (File.Exists(filePath))
                {
                    //src: http://msdn.microsoft.com/en-us/library/aa287535%28v=vs.71%29.aspx
                    string line;

                    // Read the file and display it line by line.
                    System.IO.StreamReader reader =
                       new System.IO.StreamReader(filePath);
                    while ((line = reader.ReadLine()) != null)
                        hashSet.Add(line);
                }
            }
            catch
            {
                //log exception
            }

            return hashSet;
        }

        public static void SaveFile(string filePath, HashSet<string> hashSet, SaveMode saveMode)
        {
            if (File.Exists(filePath) && saveMode == SaveMode.Overwrite)
            {
                StreamWriter writer = new StreamWriter(filePath, false);
                try
                {
                    foreach (string s in hashSet)
                    {
                        writer.WriteLine(s);
                    }
                    writer.Flush();
                }
                catch { }
                finally
                {
                    writer.Close();
                }
            }
        }
    }
}
